/*********************
*@file: file.go
*@author: jackwong
*@brief:  与文件操作接口
*@function: 实现对文件的创建|删除等功能
*@version: 1.0
*@date: 2021/5/5 16:18
*********************/
package file

import (
	"groudserver/config"
	"io/ioutil"
	"os"
	"path"
	"path/filepath"
	"time"

	"github.com/sirupsen/logrus"
)

const (
	diff_time = 3600 * 24 * 180 //告警数据保存30天
)

var (
	source string
)

// 初始化获取资源路径
func init() {
	JsonParse := config.NewJsonStruct()
	v := config.Cfg{}
	v = JsonParse.LoadCfg() //获取结构体信息
	source = v.Dir + "/Source"
}

// 目录创建
type NewFile interface {
	CreateDateDir(basePath string) (driPath, dataString string) //创建日期目录
	DelFileList(path string)                                    //删除文件
	CreteFile(filePath string) error                            //创建文件目录
	DeleteFile(str, dir string) bool                            //删除文件
}
type FileHandler struct {
}

func NewFileStruct() *FileHandler {
	return &FileHandler{}
}

// 穿件固定目录basePath
func (vp *FileHandler) CreateDateDir(basePath string) (driPath, dataString string) {
	folderName := time.Now().Format("20060102150405")
	folderPath := filepath.Join(basePath, folderName)
	if _, err := os.Stat(folderPath); os.IsNotExist(err) {
		//必须分成两步
		//1.创建新的文件夹
		os.Mkdir(folderPath, 0777)
		//2.修改权限
		os.Chmod(folderPath, 0777)
	}
	logrus.Info("文件创建成功 folderPath", folderPath, "folderName", folderName)
	return folderPath, folderName
}

// 删除14天文件目录
func (vp *FileHandler) DelFileList(path string) error {
	now_time := time.Now().Unix()
	err := filepath.Walk(path, func(path string, pfile os.FileInfo, err error) error {
		if pfile == nil {
			logrus.Error("没有获取到文件目录")
			return err
		}
		file_time := pfile.ModTime().Unix()
		if (now_time - file_time) > diff_time { //判断是否超过7天
			logrus.Info("文件路径：", path)
			os.RemoveAll(path)
		} else {
			logrus.Info("剩余文件路径", path)
		}
		return nil
	})
	if err != nil {
		logrus.Info("filePath.Walk() err=", err)
	}
	return nil
}

// 判断文件或文件夹是否存在
func (vp *FileHandler) IsFileExist(path string) (bool, error) {
	fileInfo, err := os.Stat(path)
	if os.IsNotExist(err) {
		return false, nil
	}
	//如果为0也为不存在
	if fileInfo.Size() == 0 {
		return false, nil
	}
	if err == nil {
		return true, nil
	}
	return false, err
}

// 递归创建文件夹
func (vp *FileHandler) CreteFile(filePath string) error {
	if isExist, _ := vp.IsFileExist(filePath); isExist != true {
		err := os.MkdirAll(filePath, os.ModePerm)
		return err
	}
	logrus.Info("文件已经存在!")
	return nil
}

// 删除对应的文件数据
func (vp *FileHandler) DeleteFile(str, dir string) bool {
	path := source + "/" + str
	//1.判断文件是否存在
	logrus.Info("文件路径为:", path)
	isExist, msg := vp.PathExists(path)
	//2、如果存在则返回ok
	if isExist == true {
		os.RemoveAll(path)
		logrus.Error("删除成功 msg", msg)
		//判断目录是否为空，如果目录为空也删除
		pfile := source + "/" + dir
		pdir, _ := ioutil.ReadDir(pfile)
		if len(pdir) == 0 {
			os.RemoveAll(pfile)
			logrus.Info("该文件目录为空，删除的该目录:", pfile)
		} else {
			logrus.Info("该路径目录不为空")
		}
		return true
	} else {
		logrus.Error("删除失败 msg:", msg)
		return false
	}
}

func (vp *FileHandler) PathExists(path string) (bool, string) {
	logrus.Info("PathExists Path:", path)
	_, err := os.Stat(path)
	if err == nil {
		return true, "Ok"
	}
	//isNoteExist 来判断，是不是不存在的错误
	if os.IsNotExist(err) {
		return false, "Not Find Resource"
	}
	return false, "Not Find  Resource"
}

// 查找是否有空目录
func (vp *FileHandler) FindEmptyFolder(dirname string) (emptys []string, err error) {
	files, err := ioutil.ReadDir(dirname)
	if err != nil {
		return nil, err
	}
	//判断该目录下是否有空文件夹
	if len(files) == 0 {
		return []string{dirname}, nil
	}
	for _, f := range files {
		if f.IsDir() {
			edirs, err := vp.FindEmptyFolder(path.Join(dirname, f.Name()))
			if err != nil {
				return nil, err
			}
			if edirs != nil {
				emptys = append(emptys, edirs...)
			}
		}
	}
	return emptys, nil
}

func (vp *FileHandler) DelEmptyFile(filePath string) bool {
	emptys, err := vp.FindEmptyFolder(filePath)
	if err != nil {
		logrus.Println(err.Error())
		return false
	}
	for _, dir := range emptys {
		if dir == filePath {
			continue
		}
		if err := os.Remove(dir); err != nil {
			logrus.Println("删除错误:", err.Error())
		} else {
			logrus.Println("删除成功:", err.Error())
		}
	}
	return true
}
